package com.dance.netty.netty.dubbo.common.netty;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.lang.reflect.Proxy;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;



public class NettyClient {

    /**
     * 创建线程池
     */
    private static final ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

    /**
     * 用于执行远程调用的处理器
     */
    private static NettyClientHandler nettyClientHandler;

    // 编写方法使用代理模式, 获取一个代理对象
    public Object getBean(final Class<?> serviceClass, final String protocol){
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), new Class<?>[]{serviceClass}, (proxy, method, args) -> {
            if (nettyClientHandler == null) {
                initClient();
            }
            // 设置要发给服务器端的信息
            // 采用 协议头 + 参数[0] 格式
            nettyClientHandler.setParams(protocol + args[0]);
            // 线程池提交一个任务
            return executorService.submit(nettyClientHandler).get();
        });
    }



    private static void initClient(){
        nettyClientHandler = new NettyClientHandler();
        NioEventLoopGroup eventExecutors = new NioEventLoopGroup();
        try {
            Bootstrap bootstrap = new Bootstrap();
            bootstrap.group(eventExecutors)
                    .channel(NioSocketChannel.class)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline()
                                    .addLast("stringDecoder", new StringDecoder())
                                    .addLast("stringEncoder", new StringEncoder())
                                    .addLast("nettyClientHandler", nettyClientHandler);
                        }
                    });
            bootstrap.connect("127.0.0.1", 7000).sync();
            // 注意 Client端不能阻塞
//            sync.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 重点 千万不要关闭
//            eventExecutors.shutdownGracefully();
        }
    }



}
